package deprecated;

/* matchPath enthält den Vergleich von source und tmSource und gibt für jeden Vergleich der beiden über Minimum Edit Distance eins der vier möglichen
 * Features aus: "Match", "Replacement", "Insertion", "Deletion"
 */

/* Insertion enthält die Wörter der source, die nicht in der tmsource vorkommen an den richtigen Positionen und sonst null 
 * die Elemente der Insertion sollen hinterhernicht in der tmsource vorkommen an den richtigen Positionen und sonst null 
 * die Elemente der Insertion sollen hinterher nicht in xml-tags stehen, sondern außerhalb, da sie via smt übersetzt werden müssen
 */

/* matchedTarget enthält boolesche Werte, an den Stellen in denen in der source ein Match zur tmSource gefunden wurde, ist matchTarget = true,
 *  ansonsten false -> aus dieser Information lässt sich ermitteln, welche Wörter direkt in den xml-tag übernommen werden können, nämlich
 *  die Übersetzung aus tmTarget, wo source[i] einem Wort in tmSource entspricht -> ermitteln über alignment
 *  Zwei Schritte: 
 *  1)für source[i] das Wort aus tmSource finden, das source[i] entspricht
 *  2)für das targetWord die Position merken und entsprechende tmTarget über alignment suchen
 */

/* numberOfMismatchAreas dient dazu, ausreichend viele insT zu finden, um anschließend in die xml-tags entsprechend viele noch über smt zu übersetzende
 * Bereiche einzufügen
 */


import java.util.*;

/**
 * Constructs an xml frame.
 * The xml-tags contains the words which have been translated yet.
 * Words outside xml-tags have to be translated via statistical machine translation.
 *
 * @author Sabrina
 *
 */
public class MatchTar {

        //Initialize Arrays: source, tmsource, target and matchedTarget
        private String[] source;
        private String[] tmsource;
        private String[] target;
        private boolean[] matchedTarget;
        private String[] insertion = new String[0];
        private String[] matchPathArr;
        
        //Contains alignments
        private Map<String, String> alignment = new HashMap<String, String>();
       

        public MatchTar(String[] source, String[] tmsource, String[] tmtarget, Map<String,String> alignment){
        	this.source = source;
        	this.target = tmtarget;
        	this.tmsource = tmsource;
        	this.alignment = alignment;
        	
        	//length correlates with the length of longer input
        	DistanceSetArray matchPath = new DistanceSetArray(this.source, this.tmsource);
        	ArrayList<String> dummy = matchPath.getBacktrace();
        	this.matchPathArr = new String[dummy.size()];
        	for(int i=0; i<dummy.size();i++){
        		this.matchPathArr[i] = dummy.get(i);
        	}
        	
        	insertion = new String[matchPathArr.length];
        }
        
        
        /**
         * Finds the mismatched area and gives it to the mismatch-function
         * @return Returns the return-value of the method constructXml as String
         * source: to be translated
         * tmsource: FuzzyMatch out of translation memory
         * target: translation of tmsource
         */
        public String findMismatch(){
               
        		System.out.println(Arrays.toString(this.matchPathArr));
        		System.out.println("source: "+Arrays.toString(this.source));
        		System.out.println("tmSource: "+Arrays.toString(this.tmsource));
        		System.out.println("target: "+Arrays.toString(this.target));
               
                //declaration and initialization of index-variables
                int posI=0;
                int posS=0;
               
                int startI = 0;
                int startS = 0;
               
                String edit = "";
               
                boolean matching = false;
                
              //*******************************************matchedTarget written*********************************
                matchedTarget = new boolean[matchPathArr.length];
                for (int i=0; i<matchedTarget.length; i++){
                        matchedTarget[i] = true;
                }
                
                //Comparing source and tmsource
                //TODO entfernt: matchPathArr -1
                for(int i = 0; i<this.matchPathArr.length; i++){
                       
                        //Set edit to Match / Replacement / Insertion / Deletion
                        edit = this.matchPathArr[i];
                        
                        //BEGINNING OF MISMATCH
                        if(matching && edit != " Match "){
                                startI = posI;
                                startS = posS;
                                matching = false;
                        }
               
                        //END OF MISMATCH
                        else if(!matching && edit == " Match "){
                        		System.out.println("Aufruf1");
                                mismatch(startI, posI-1, startS, posS-1);
                                matching = true;
                        }
                      
                       
                        if(!edit.equals(" Deletion ")){
                                posI++;
                        }
                               
                        if(!edit.equals(" Insertion ")){
                                posS++;
                        }
                }
                               
                if(!matching){
                		System.out.println("Aufruf2");
                        mismatch(startI, posI, startS, posS);
                }
               
                return constructXml();
               
        }

        /**
         * Finds the insertion position for source-words that aren´t in tmSource, no return value
         * @param startI: is start-index of mismatch in the source
         * @param endI: is end-index of mismatch in the source
         * @param startS: is start-index of mismatch in the tmSource
         * @param endS:is end-index of mismatch in the tmSource
         */
        private void mismatch(int startI, int endI, int startS, int endS) {
               
        		int size = endS-startS;
        		if(size == -1){
        			size++;
        		}
        		int ind = 0;
               
        		//*******************************************matchedTarget written*********************************
        		
              //matchedTarget wird falsch, an zugehöriger target-Stelle der tmsource im Bereich von startS und endS
                String[] aligned = new String[size];
                for(int i=startS; i<endS; i++){
                	aligned[ind] = tmsource[i];
                	ind ++;
                }
                for(String align : aligned){
                	 for(int i=0; i<target.length; i++){
                     	if (alignment.get(align).equals(target[i])){
                     		matchedTarget[i] = false;
                     		continue;
                     	}
                     }
                }
                System.out.println("matchedTarget: "+Arrays.toString(matchedTarget));
               
                int insT = -1;
                boolean insTSet = false;

                int size2 = endS-startS+1;
                //construct alignments von tmsource sorted by target
                
                String[] startSendSArr = new String[size2];
                int[] indArr = new int[size2];
                
                if(size >0 ){
                	int counter = 0;
                	//TODO
                	//< oder <= endS????
                
                	if (endS == tmsource.length){
            			endS--;
            		}
                	for(int i=startS; i<=endS; i++){
                		loop2: for(int j=0; j<target.length; j++){
                			if(alignment.get(tmsource[i]).equals(target[j])){
                				startSendSArr[counter] = target[j];
                				indArr[counter] = j;
                				counter++;
                				break loop2;
                			}
                		}
                	}
                }
                
                //calcMin of TargetPositions
                int min = 100;
          	  	for(int number:indArr){
          	  		if(number < min){
          	  			min = number;
          	  		}
          	  	}
          	  	if(min != 100){
          	  		insT = min;
          	  		insTSet = true;
          	  	}
               
                //insT undefined -> augment the frame of mismatchTmSource
                int counter = 100;

                while(insTSet==false && counter >0 ){
                	for(int i=0; i<this.target.length; i++){
                		counter--;
                		if(startS >0){
                			if(this.target[i].equals(alignment.get(source[--startS]))){
                				insT = i;
                				insTSet = true;
                				break;
                			}
                        }
                	}
                }
	               
	                if(insTSet == false){
	                    //sentence start
	                	insT = -1;
	                    //end
	                	if (endI == this.source.length){
	                		insT = this.source.length;
	                    }
	                }
	               
	                	if(source.length > tmsource.length || source.length == tmsource.length){
	                		
	                		if(endI == source.length){
	                			endI --;
	                		}
	                		//***********************************************INSERTION WRITTEN**********************************
	                	//	System.out.println("startI: "+startI +"endI: "+endI+" this.source[i]");
	                		
	                        for (int i = startI; i<=endI; i++){
	                        //	System.out.println("i: "+i);
	                                insertion[i] = this.source[i];
	                                insT++;
	                        }
	                	}
	                	else{
	                        for (int i = startI; i<endI; i++){
	                                insertion[i] = this.source[i];
	                                insT++;
	                        }
	                	}
	                	//System.out.println("Insertion: "+Arrays.toString(insertion));
	                }
        /**
         * Constructs a xml via given data (matchedTarget, insertion)
         *
         * @return a xml-construct as String
         * containing the translated words in xml-tags and the residual words outside
         * residual words must be translated via statistical machine translation
         */
        private String constructXml() {
               
                String xml = "";
                boolean included = false;
                int startT = -1;
                
                	//int maxlen = Math.max(source.length, target.length);
                	//TODO Sollte doch nur über target.length gehen, damit keine IndexOutOfBound entstehen oder?
	                for (int t=0; t<target.length; t++){
	                    //verifies whether insertion[t] is defined
	                	//für den Fall, dass nach dem letzten Mismatch nur noch Matches auftreten, um Aufruf von xml-Erweiterung zu erzielen
	                	
	                	//System.out.println("startT: "+startT);
	                        if(!included && matchedTarget[t]){
	                                included = true;
	                        }
	                       
	                        else if(included && (!matchedTarget[t] || insertion[t]!= null)){
	                                startT++;
	                                if(startT >= 0){
	                                        xml += " " +"<xml translation= ";
	                                        if(insertion[t] != null){
	                                        	//wenn zwei oder mehr Elemente eingefügt werden muss zwischen je zwei Elementen 
	                                        	//zusätzl startT erhöht werden
	                                        	int counter =0;
	                                        	for (int j=startT; j<t; j++){
	                                                xml += target[j]+" ";
	                                                counter++;
	                                            }
	                                        	//damit mehrere wörter eingefügt werden können und nicht nochmal aufgerufen werden
	                                        	if(counter>1){
	                                        		startT = startT + counter;
	                                        	}
	                                        }
	                                        xml += "> </xml>";
	                                }
	                                included = false;
	                        }
	                        if (insertion[t] != null){
	                                xml += " "+insertion[t];
	                        }
	                }
           //     }
                int tailCount =0;
            	for(int i=matchPathArr.length-1; i>=0; i--){
            		if(matchPathArr[i].equals (" Match ")){
            			tailCount ++;
            		}
            		else{
            			break;
            		}
            	}
            	if(tailCount >0){
	            	int addEl = target.length-tailCount;
	            		
	            	xml += " " +"<xml translation=";
	            	while(addEl <= target.length-1){
	            		xml += " " + target[addEl];
	            		addEl ++;
	            	}
	            	xml += "</xml>";
            	}
            	
                return xml;
        }

       
        /**
         * @param args
         */
        public static void main(String[] args) {
        	
        		String[] s = "der ast ist grün".split(" ");
                String[] tms = "der stamm ist grün".split(" ");
                String[] tmt = "the trunk is green".split(" ");
                Map<String,String> alignment = new HashMap<String,String>();
                alignment.put("der", "the"); alignment.put("stamm", "trunk"); alignment.put("ist", "is");
                alignment.put("grün", "green"); alignment.put("x", "x");
                
                MatchTar set1 = new MatchTar(s,tms,tmt,alignment);
               
                System.out.println(set1.findMismatch());
                  
	               

	        }

}